import traceback
import subprocess
import pandas as pd
import csv
import os
import shutil
from IPython import embed
from git import Repo
from mailing import send_mail_cse_smtp
from sys import argv
from subprocess import check_output
from urllib.parse import urlparse


def clone(target_dir, key_path, git_url, flog):
    key_path = os.path.abspath(key_path)
    target_dir = os.path.abspath(target_dir)
    if len(git_url) == 0:
        raise NameError(f"No Submission.")

    if git_url.startswith("https"):
        url_content = urlparse(git_url).path
    else:
        url_content = git_url.replace("git@github.com:", "")

    success = False
    tried_cmds = []
    for idx, prefix in enumerate(
        ["git@github.com:", "https://github.com/", "https://gitee.com/"]
    ):
        try:
            git_url = prefix + url_content

            if os.path.isdir(target_dir):
                print("pull try [{}]".format(idx))

                trackall_cmd = """git branch -r | grep -v '\->' | while read remote; do git branch --track "${remote#origin/}" "$remote"; done"""

                if git_url.startswith("git@"):
                    cmd = f"cd {target_dir}; ssh-agent bash -c 'ssh-add {key_path}; git fetch --all; git pull --all'"
                    print(cmd)
                elif git_url.startswith("http"):
                    cmd = f"cd {target_dir}; git fetch --all; git pull --all"
                else:
                    raise NameError(f"Bad git url")
            else:
                print("clone try [{}]".format(idx))
                # clone
                if git_url.startswith("git@"):
                    cmd = f"ssh-agent bash -c 'ssh-add {key_path}; git clone {git_url} {target_dir}'"
                elif git_url.startswith("http"):
                    cmd = f"git clone {git_url} {target_dir}"
                else:
                    raise NameError(f"Bad git url")
                    cmd = "N/A"

            tried_cmds.append(cmd)
            check_output(
                cmd,
                shell=True,
            )

            success = True
            print("Success!")
            break
        except Exception:
            print(traceback.format_exc())
            pass

    if not success:
        flog.write("Failed on {}:\n".format(target_dir))
        flog.write("Failed cmds:\n")
        for cmd in tried_cmds:
            flog.write("{}\n".format(cmd))
        if any(["clone" in cmd for cmd in tried_cmds]):
            shutil.rmtree(target_dir)
        raise RuntimeError("Cannot get code to {}".format(target_dir))

    repo = Repo(target_dir)

    branch = repo.heads[0]
    return branch.name, branch.commit.hexsha, branch.commit.authored_datetime


# group_prefix = "D"  # for TA use
group_prefix = ""  # for TA use

if __name__ == "__main__":
    df = pd.read_csv("./final-group.csv")

    group_id = df["Group ID"]
    pj_name = df["Project Name"]
    url = df["URL"]
    failed_list = []

    flog = open("pull.log", "w")
    for idx in range(len(group_id)):
        gid = group_id[idx]
        if group_prefix and not gid.startswith(group_prefix):
            continue

        print("Processing {}".format(gid))
        try:
            # git clone and set commit id
            target_dir = f"./final_codes/group_{gid}"
            key_path = f"./keys2021/id_rsa_group_{gid}"
            clone(target_dir, key_path, url[idx], flog)
            flog.write("success\n")
        except:
            failed_list.append(idx)
            print(traceback.format_exc())

    failed_log = "Failed on {}\n".format([group_id[idx] for idx in failed_list])
    flog.write(failed_log)
    print(failed_log)
